/*global FBL */
FBL.ns(function () {
	with (FBL) {
		var panelName = "friendlyFire";
		
		window.addEventListener("load", function () {
			gBrowser.addEventListener("load", autoRunFriendlyFire, false);
		}, false);
		
		function autoRunFriendlyFire () {
			var autoRun = Firebug.getPref(Firebug.prefDomain, "friendlyfire.autorun");
			if (autoRun && content.location.href !== "about:blank") {
				if (typeof friendlyfire !== "undefined") {
					friendlyfire.autorun = true;
				}
				var runButton = document.getElementById("friendlyfireRunButton");
				runButton.click();
			}
			else {
				var clearButton = document.getElementById("friendlyfireClearButton");
				clearButton.click();
			}
		}
		
		Firebug.friendlyFireModel = extend(Firebug.Module, {
		    showPanel: function(browser, panel) {
				var isPanel = panel && panel.name === panelName;
				var friendlyFireButtons = browser.chrome.$("fbfriendlyfireButtons");
				collapse(friendlyFireButtons, !isPanel);
		    },
		
			addStyleSheet : function (doc) {
				var styleSheet = document.getElementById("friendlyfire-firebug-style");
				if (!styleSheet) {
					styleSheet = createStyleSheet(doc, "chrome://friendlyfire/skin/friendlyfire-firebug.css");
					styleSheet.id = "friendlyfire-firebug-style";
					addStyleSheet(doc, styleSheet);
				}
			},

		   	onRun: function (context, results) {
		        var panel = context.getPanel(panelName),
					parentNode = panel.panelNode,
					//results = results || friendlyfire.run(),
					results = friendlyfire.run(),
					findInlineEvents = Firebug.getPref(Firebug.prefDomain, "friendlyfire.inlineEvents"),
					findInlineStyle = Firebug.getPref(Firebug.prefDomain, "friendlyfire.inlineStyle"),
					findJavaScriptLinks = Firebug.getPref(Firebug.prefDomain, "friendlyfire.javascriptLinks"),
					highlightAllEvents = Firebug.getPref(Firebug.prefDomain, "friendlyfire.highlightAllEvents"),
					inlineEventsClass = (highlightAllEvents)? " class='checked'" : "";
				
				if (results) {
					//if (!results.autorun) {
						var browser = FirebugChrome.getCurrentBrowser();
						browser.chrome.selectPanel(panelName);
						Firebug.toggleBar(true, panelName);
					//}
					
					//alert(results.replace(/</g, "&lt;").replace(/>/g, "&gt;"));
					//alert(typeof results);
					//alert(content.document.body.innerHTML);
					//content.document.body.innerHTML = results.replace(/</g, "<br>&lt;").replace(/>/g, "&gt;<br>");
					//alert("After: " + content.document.body.innerHTML);
					//results = results.replace(/</g, "<br>&lt;").substring(0, 100);
					//results = results.split("<");
					
					// var code = "";
					// 					for (var i=0, il=results.length; i<il; i++) {
					// 						code += "<div>" + results[i] + "</div>";
					// 					}
					
					//alert(code.replace(/</g, "&lt;"));
					
					var friendlyFireReport = domplate({
						reportListing:
							DIV({class: "friendlyfire-result-container"},
									H2(
										{},
										"Retrieved DOM:"
									),
									DIV(
										{},
										results
										// FOR("item", "data.items|resultIterator", 
										// 											DIV(
										// 												{},
										// 												"$item"
										// 											)	
										// 										)
									
										// for (var i=0, il=10; i<il; i++) {
										// 										DIV(
										// 											{},
										// 											i
										// 										)
										// 									}
										//results
										//results.replace(/</g, "<br>&lt;").replace(/>/g, "&gt;<br>").substring(0, 100)
										//results.replace(/</g, "&lt;").replace(/>/g, "&gt;")
										//results.split(">").join("\n")//replace(/</g, "&lt;")
									)
						        ),
						resultIterator: function(result) {
							if (!result)
							return [];

							if (result instanceof Array)
							return result;

							return [result];
						}
					});
					//alert(document.getElementById("friendlyfire-result-container"));
					friendlyFireReport.reportListing.replace({}, parentNode, friendlyFireReport);
				}
				else {
					this.onClear.call(this, context);
				}
				if (typeof friendlyfire !== "undefined") {
					friendlyfire.autorun = false;
				}
		    },
		
			onToggle : function (context) {
				var results = friendlyfire.toggle();
				this.onRun.call(this, context, results);
			},
		
			onClear: function (context) {
				var browser = FirebugChrome.getCurrentBrowser();
				//browser.chrome.selectPanel(panelName);
				
		        var panel = context.getPanel(panelName);
			    var parentNode = panel.panelNode;
				friendlyfire.clearAll();
				friendlyfire.clearState();
				var friendlyFireReport = domplate({
					reportListing :
						DIV({class: "friendlyfire-result-container"},
							H1({}, "Friendly Fire for Firebug"),
							DIV({class: "instructions"}, 
								P({}, "Click Run or Toggle above in the menu bar to activate Friendly Fire"),
								P({}, "Enable/disable Autorun and set what to look for under the Options menu to the right")
							)
						)	
				});
				friendlyFireReport.reportListing.replace({}, parentNode, null);
		    },
		
			onHide: function (context) {
				Firebug.toggleBar(false, panelName);
		    }
		});
			
		
		function friendlyFirePanel () {
			
		}
		friendlyFirePanel.prototype = extend(Firebug.Panel, {
			name : panelName,
			title : "Friendly Fire",
			initialize : function () {
				Firebug.Panel.initialize.apply(this, arguments);
				Firebug.friendlyFireModel.addStyleSheet(this.document);
				friendlyfire.init();
			},
			
			getOptionsMenuItems : function () {
				return [
					this.optionsMenuItem("Autorun", "friendlyfire.autorun"),
					this.optionsMenuItem("Inline JavaScript Events", "friendlyfire.inlineEvents"),
					this.optionsMenuItem("Inline Style", "friendlyfire.inlineStyle"),
					this.optionsMenuItem("javascript: links", "friendlyfire.javascriptLinks"),
					this.optionsMenuItem("Highlight all events", "friendlyfire.highlightAllEvents")
				];
			},
			
			optionsMenuItem : function  (text, option) {
				var pref = Firebug.getPref(Firebug.prefDomain, option);
				return {
					label : text,
					type : "checkbox",
					checked : pref,
					command : bindFixed(Firebug.setPref, this, Firebug.prefDomain, option, !pref)
				};
			}
		});
		
		Firebug.registerModule(Firebug.friendlyFireModel);
		Firebug.registerPanel(friendlyFirePanel);
	}
});

var friendlyfire = function () {
	var states = {
		
	};
	return {
		autorun : false,
		
		init : function () {
			content.addEventListener("unload", function () {
				friendlyfire.clearAll.apply(friendlyfire, arguments);
				friendlyfire.clearState.apply(friendlyfire, arguments);
			}, false);
		},
		
		getTabIndex : function () {
			var browsers = gBrowser.browsers,
				tabIndex;
			for (var i=0, il=browsers.length; i<il; i++) {
				if(gBrowser.getBrowserAtIndex(i).contentWindow == content) {
					tabIndex = i;
					break;
				}
			}
			return tabIndex;
		},
		
		getState : function () {
			var tabIndex = this.getTabIndex(),
				state = states[tabIndex];
			return state;	
		},
		
		clearState : function () {
			var state = this.getState();
			if (state) {
				this.clearAll();
				state.hasRun = false;
			}
		},
		
		toggle : function  () {
			var state = this.getState(),
				tabIndex = this.getTabIndex();
			
			if(!state) {
				state = states[tabIndex] = {
					hasRun : false,
					affectedElms : []
				};
			}
			this.clearAll();
			
			if (state.hasRun) {
				state.hasRun = false;
				this.clearAll();
				return {};
			}
			else {
				state.hasRun = true;
				return this.run();
			}
		},
			
		run : function () {
			var state = this.getState(),
				tabIndex = this.getTabIndex();
				//findInlineEvents = Firebug.getPref(Firebug.prefDomain, "friendlyfire.inlineEvents"),

			if(!state) {
				state = states[tabIndex] = {
					affectedElms : []
				};
			}
			state.hasRun = true;
			this.clearAll();
			
			// Needed to be here to make sure HTML elements are retrieved from the active tab
			var allElms = content.document.getElementsByTagName("*"),
				htmlElm = content.document.getElementsByTagName("html")[0],
				attributes = htmlElm.attributes,
				elmsString = "<html",
				elmObj = {};
				
			for (var i=0, il=attributes.length, attribute; i<il; i++) {
				attribute = attributes[i];
				elmsString += " " + attribute.name + "=\"" + attribute.value + "\"";
			};
			elmsString += ">" + htmlElm.innerHTML + "</html>";
			
			var indentLevel = 0;
			var code = "",
				childNodes;
			while (htmlElm && htmlElm.childNodes) {
				code += "&lt;" + htmlElm.nodeName;
				attributes = htmlElm.attributes;
				for (var i=0, il=attributes.length, attribute; i<il; i++) {
					attribute = attributes[i];
					code += " " + attribute.name + "=&quot;" + attribute.value.replace(/"/g, "&quot;") + "&quot;";
				}
				code += "&gt;<br>";
				childNodes = htmlElm.getElementsByTagName("*");
				for (var i=0, il=childNodes.length, attribute; i<il; i++) {
					code += "&lt;" + childNodes[i].nodeName;
					attributes = childNodes[i].attributes;
					for (var j=0, jl=attributes.length, attribute; j<jl; j++) {
						attribute = attributes[j];
						code += " " + attribute.name + "=&quot;" + attribute.value.replace(/"/g, "&quot;") + "&quot;";
					}
					code += "&gt;<br>";
					code += "&lt;/" + childNodes[i].nodeName + "&gt;";
				}
				code += "&lt;/" + htmlElm.nodeName + "&gt;";
				htmlElm = null;
			}
			
			var data = [];
			for (var x=0, xl=allElms.length; x<xl; x++) {
				tagCode = "&lt;" + allElms[x].nodeName;
				attributes = allElms[x].attributes;
				for (var i=0, il=attributes.length, attribute; i<il; i++) {
					attribute = attributes[i];
					tagCode += " " + attribute.name + "=&quot;" + attribute.value.replace(/"/g, "&quot;") + "&quot;";
				}
				tagCode += "&gt;";
				//data.push(tagCode);
			}
			
			
			elmsString = elmsString.replace(/[<>"]/g, function (match) {
				var retVal = match;
				if (match === "<") {
					retVal = "&lt;";
				}
				else if (match === ">") {
					retVal = "&gt;";
				}
				else if (match === "\"") {
					retVal = "&quot;";
				}
				return retVal;
			});
			
			
			//alert(elmsString);
			
			return code;
		},
		
		clear : function () {
			
		},
		
		clearAll : function () {
			var state = this.getState();
			if (state) {
				var affectedElms = state.affectedElms;
				this.clear();
			}
		}
	};
}();